#ifndef FloatingDragPreviewH
#define FloatingDragPreviewH
//============================================================================
/// \file   FloatingDragPreview.h
/// \author Uwe Kindler
/// \date   26.11.2019
/// \brief  Declaration of CFloatingDragPreview
//============================================================================

//============================================================================
//                                   INCLUDES
//============================================================================
#include <QWidget>
#include "FloatingDockContainer.h"

namespace ads
{
class CDockWidget;
class CDockAreaWidget;
struct FloatingDragPreviewPrivate;

/**
 * CFloatingDragPreview是一个浮动的悬浮窗口，用于指示悬浮窗口的移动。
 * 该窗口用作非透明停靠操作的拖动操作的占位符。
 */
class CFloatingDragPreview : public QWidget, public IFloatingWidget
{
    Q_OBJECT
private:
    FloatingDragPreviewPrivate* d; // 私有变量d
    friend struct FloatingDragPreviewPrivate; // 声明FloatingDragPreviewPrivate为友元结构体

// Private slots
private Q_SLOTS:
    /**
     * 当应用程序状态变为非活动状态时，取消非透明的分离停靠
     */
    void onApplicationStateChanged(Qt::ApplicationState state);

// Protected methods
protected:
    /**
     * 处理绘制事件
     */
    virtual void paintEvent(QPaintEvent *e) override;

    /**
     * 内容是 DockArea 或 DockWidget
     */
    CFloatingDragPreview(QWidget* Content, QWidget* parent);

// Public methods
public:
    using Super = QWidget;

    /**
     * 创建一个用于分离 Content 参数中的 DockWidget 的实例
     */
    CFloatingDragPreview(CDockWidget* Content);

    /**
     * 创建一个用于分离 Content 参数中的 DockArea 的实例
     */
    CFloatingDragPreview(CDockAreaWidget* Content);

    /**
     * 删除私有数据
     */
    ~CFloatingDragPreview();

    /**
     * 我们过滤分配的内容小部件的事件，以接收取消拖动操作的 Esc 键按下事件
     */
    virtual bool eventFilter(QObject *watched, QEvent *event) override;

// Implements IFloatingWidget
public:
    virtual void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
        eDragState DragState, QWidget* MouseEventHandler) override;

    /**
     * 将小部件移动到相对于调用 startFloating() 时给定的位置的新位置
     */
    virtual void moveFloating() override;

    /**
     * 完成拖动。
     * 隐藏停靠覆盖层，并执行分离和停靠分配的内容小部件的实际操作
     */
    virtual void finishDragging() override;

    /**
     * 清理拖动小部件的自动隐藏容器（如果有）
     */
    void cleanupAutoHideContainerWidget(DockWidgetArea ContainerDropArea);

// Signals
Q_SIGNALS:
    /**
     * 如果通过 Esc 键或通过任务管理器的活动应用程序切换取消拖动，则发出此信号
     */
    void draggingCanceled();
};


} // namespace ads

//---------------------------------------------------------------------------
#endif // FloatingDragPreviewH

